package com.like.bluetooth.classic.client.connect.callback

import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import com.like.bluetooth.callback.BluetoothCallback
import com.like.bluetooth.exception.BluetoothExceptionDeviceDisconnected
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch

class ConnectCallbackManager(private val address: String?) {
    private val broadcastReceiver by lazy {
        object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                when (intent?.action) {
                    BluetoothDevice.ACTION_ACL_CONNECTED -> {
                        // 当设备连接时触发
                        val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE) ?: return
                        // 此处需要判断地址来确定是否是正确的设备。因为此回调在其它低功耗蓝牙设备连接成功后也触发，从而造成错误回调。
                        if (device.address == address) {
                            // 更新UI或其他逻辑
                            connectBluetoothCallback?.onSuccess(device)
                        }
                    }

                    BluetoothDevice.ACTION_ACL_DISCONNECTED -> {
                        // 当设备断开连接时触发
                        val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE) ?: return
                        if (device.address == address) {
                            // 更新UI或其他逻辑
                            connectBluetoothCallback?.onError(BluetoothExceptionDeviceDisconnected(device.address))
                        }
                    }
                }
            }
        }
    }
    private var job: Job? = null
    private var readCallback: BluetoothCallback<ByteArray>? = null
    private var connectBluetoothCallback: BluetoothCallback<BluetoothDevice>? = null
    private val readBuffer: ByteArray = ByteArray(1024)

    fun init(scope: CoroutineScope, socket: BluetoothSocket?) {
        job?.cancel()
        job = scope.launch(Dispatchers.IO) {
            var numBytes: Int
            while (isActive) {
                try {
                    socket?.inputStream?.let {
                        if (it.available() > 0) {
                            numBytes = it.read(readBuffer)
                            if (numBytes > 0) {
                                readCallback?.onSuccess(readBuffer.copyOf(numBytes))
                            }
                        }
                    }
                } catch (e: Exception) {
                }
                // 延迟10ms，避免CPU占用过高，并且可以避免丢失数据和连接断开（下面两个bug，当 read partial size 达到 20 时，会断开连接）。
                // 2024-07-15 09:31:16.020 W/BluetoothSocket: readAll() looping, read partial size: 7, expect size: 20
                // 2024-07-15 09:31:16.087 W/System.err: java.io.IOException: Connection failure, wrong signal size: 18263
                delay(10)
            }
        }
    }

    fun cancelJob() {
        job?.cancel()
        job = null
    }

    fun registerBroadcastReceiver(context: Context) {
        context.registerReceiver(broadcastReceiver, IntentFilter().apply {
            addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
            addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
        })
    }

    fun unregisterBroadcastReceiver(context: Context) {
        try {
            context.unregisterReceiver(broadcastReceiver)
        } catch (e: Exception) {
        }
    }

    fun setReadCallback(callback: BluetoothCallback<ByteArray>?) {
        readCallback = callback
    }

    fun setConnectBleCallback(callback: BluetoothCallback<BluetoothDevice>?) {
        connectBluetoothCallback = callback
    }

}
